module Timer(clk, lock, abus, dbus, we);
	input clk, lock;
	input [31:0] abus;
	inout [31:0] dbus;
	input we;
	parameter CLOCKS_PER_MS;
	
	reg [31:0] count = 0,limit = 0,count_to_ms = 0;
	reg [7:0] ctrl;
	
	wire sigms = (count_to_ms == CLOCKS_PER_MS);
	wire siglimit = (count == (limit-1));
	
	parameter ADDRTCNT = 32'hFFFFFF20;
	parameter ADDRTLIM = 32'hFFFFFF28;
	parameter ADDRTCTL = 32'hFFFFFF24;
	parameter BITREADY = 0;
	parameter BITOVRRN = 2;
	parameter BITIE    = 8;
	
	wire selCtl=(abus == ADDRTCTL);
	wire selCnt=(abus == ADDRTCNT);
	wire selLim=(abus == ADDRTLIM);
	wire wrCtl=we&&selCtl;
	wire rdCtl=(!we)&&selCtl;
	wire wrCnt=we&&selCnt;
	wire rdCnt=(!we)&&selCnt;
	wire wrLim=we&&selLim;
	wire rdLim=(!we)&&selLim;

	wire reset = !lock;
	
	always @(posedge clk or posedge reset) begin
		if (reset) begin
			count <= 32'b0;
			limit <= 32'b0;
			count_to_ms <= 32'b0;
			ctrl <= 8'b0;
		end
		else begin
			if (sigms) begin
				count <= count + 1;
				count_to_ms <= 32'b0;
				if (siglimit) begin
					count <= 32'b0;
					// update control register
					ctrl[BITREADY] <= 1'b1;
					if (ctrl[BITREADY])
						ctrl[BITOVRRN] <= 1'b1;
				end
			end
			else begin
				count_to_ms <= count_to_ms + 1;
			end
			
			// bus interface
			if (wrCnt)
					count <= dbus;
			else if (wrLim)
					limit <= dbus;
			else if (wrCtl) begin
				if (!dbus[BITREADY])
					ctrl[BITREADY] <= 1'b0;
				if (!dbus[BITOVRRN])
					ctrl[BITOVRRN] <= 1'b0;
			end
		end
	end

	assign dbus = rdCtl ? {24'b0,ctrl} :
						rdCnt ? count :
						rdLim ? limit :
						32'hZZZZZZZZ;

endmodule
